home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / libtiff / tif_read.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  546 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_read.c,v 1.51 92/10/26 17:08:25 sam Rel $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  * Scanline-oriented Read Support
  32.  */
  33. #include "tiffiop.h"
  34.  
  35. #if USE_PROTOTYPES
  36. static    int TIFFFillStrip(TIFF *, u_int);
  37. static    int TIFFFillTile(TIFF *, u_int);
  38. static    int TIFFStartStrip(TIFF *, u_int);
  39. static    int TIFFStartTile(TIFF *, u_int);
  40. static    int TIFFCheckRead(TIFF *, int);
  41. #else
  42. static    int TIFFFillStrip();
  43. static    int TIFFFillTile();
  44. static    int TIFFStartStrip();
  45. static    int TIFFStartTile();
  46. static    int TIFFCheckRead();
  47. #endif
  48.  
  49. /*
  50.  * Seek to a random row+sample in a file.
  51.  */
  52. static int
  53. DECLARE3(TIFFSeek, TIFF*, tif, u_int, row, u_int, sample)
  54. {
  55.     register TIFFDirectory *td = &tif->tif_dir;
  56.     int strip;
  57.  
  58.     if (row >= td->td_imagelength) {    /* out of range */
  59.         TIFFError(tif->tif_name, "%d: Row out of range, max %d",
  60.             row, td->td_imagelength);
  61.         return (0);
  62.     }
  63.     if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  64.         if (sample >= td->td_samplesperpixel) {
  65.             TIFFError(tif->tif_name,
  66.                 "%d: Sample out of range, max %d",
  67.                 sample, td->td_samplesperpixel);
  68.             return (0);
  69.         }
  70.         strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
  71.     } else
  72.         strip = row / td->td_rowsperstrip;
  73.     if (strip != tif->tif_curstrip) {     /* different strip, refill */
  74.         if (!TIFFFillStrip(tif, strip))
  75.             return (0);
  76.     } else if (row < tif->tif_row) {
  77.         /*
  78.          * Moving backwards within the same strip: backup
  79.          * to the start and then decode forward (below).
  80.          *
  81.          * NB: If you're planning on lots of random access within a
  82.          * strip, it's better to just read and decode the entire
  83.          * strip, and then access the decoded data in a random fashion.
  84.          */
  85.         if (!TIFFStartStrip(tif, strip))
  86.             return (0);
  87.     }
  88.     if (row != tif->tif_row) {
  89.         if (tif->tif_seek) {
  90.             /*
  91.              * Seek forward to the desired row.
  92.              */
  93.             if (!(*tif->tif_seek)(tif, row - tif->tif_row))
  94.                 return (0);
  95.             tif->tif_row = row;
  96.         } else {
  97.             TIFFError(tif->tif_name,
  98.             "Compression algorithm does not support random access");
  99.             return (0);
  100.         }
  101.     }
  102.     return (1);
  103. }
  104.  
  105. int
  106. /*VARARGS3*/
  107. DECLARE4(TIFFReadScanline, TIFF*, tif, u_char*, buf, u_int, row, u_int, sample)
  108. {
  109.     int e;
  110.  
  111.     if (!TIFFCheckRead(tif, 0))
  112.         return (-1);
  113.     if (e = TIFFSeek(tif, row, sample)) {
  114.         /*
  115.          * Decompress desired row into user buffer.
  116.          */
  117.         e = (*tif->tif_decoderow)
  118.             (tif, buf, tif->tif_scanlinesize, sample);
  119.         tif->tif_row++;
  120.     }
  121.     return (e ? 1 : -1);
  122. }
  123.  
  124. /*
  125.  * Read a strip of data and decompress the specified
  126.  * amount into the user-supplied buffer.
  127.  */
  128. int
  129. DECLARE4(TIFFReadEncodedStrip,
  130.     TIFF*, tif, u_int, strip, u_char*, buf, u_long, size)
  131. {
  132.     TIFFDirectory *td = &tif->tif_dir;
  133.     u_long nrows, stripsize;
  134.  
  135.     if (!TIFFCheckRead(tif, 0))
  136.         return (-1);
  137.     if (strip >= td->td_nstrips) {
  138.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  139.             strip, td->td_nstrips);
  140.         return (-1);
  141.     }
  142.     /*
  143.      * Calculate the strip size according to the number of
  144.      * rows in the strip (check for truncated last strip).
  145.      */
  146.     if (strip != td->td_nstrips-1 ||
  147.         (nrows = td->td_imagelength % td->td_rowsperstrip) == 0)
  148.         nrows = td->td_rowsperstrip;
  149.     stripsize = TIFFVStripSize(tif, nrows);
  150.     if (size == (u_long)-1)
  151.         size = stripsize;
  152.     else if (size > stripsize)
  153.         size = stripsize;
  154.     return (TIFFFillStrip(tif, strip) && 
  155.     (*tif->tif_decodestrip)(tif, buf, size, strip / td->td_stripsperimage) ?
  156.         size : -1);
  157. }
  158.  
  159. static int
  160. DECLARE5(TIFFReadRawStrip1,
  161.     TIFF*, tif, u_int, strip, u_char*, buf, u_long, size, const char*, module)
  162. {
  163.     TIFFDirectory *td = &tif->tif_dir;
  164.  
  165.     if (!isMapped(tif)) {
  166.         if (!SeekOK(tif, td->td_stripoffset[strip])) {
  167.             TIFFError(module,
  168.                 "%s: Seek error at scanline %d, strip %d",
  169.                 tif->tif_name, tif->tif_row, strip);
  170.             return (-1);
  171.         }
  172.         if (!ReadOK(tif, buf, size)) {
  173.             TIFFError(module, "%s: Read error at scanline %d",
  174.                 tif->tif_name, tif->tif_row);
  175.             return (-1);
  176.         }
  177.     } else {
  178.         if (td->td_stripoffset[strip] + size > tif->tif_size) {
  179.             TIFFError(module,
  180.                 "%s: Seek error at scanline %d, strip %d",
  181.                 tif->tif_name, tif->tif_row, strip);
  182.             return (-1);
  183.         }
  184.         memcpy(buf, tif->tif_base + td->td_stripoffset[strip], size);
  185.     }
  186.     return (size);
  187. }
  188.  
  189. /*
  190.  * Read a strip of data from the file.
  191.  */
  192. int
  193. DECLARE4(TIFFReadRawStrip,
  194.     TIFF*, tif, u_int, strip, u_char*, buf, u_long, size)
  195. {
  196.     static const char module[] = "TIFFReadRawStrip";
  197.     TIFFDirectory *td = &tif->tif_dir;
  198.     u_long bytecount;
  199.  
  200.     if (!TIFFCheckRead(tif, 0))
  201.         return (-1);
  202.     if (strip >= td->td_nstrips) {
  203.         TIFFError(tif->tif_name, "%d: Strip out of range, max %d",
  204.             strip, td->td_nstrips);
  205.         return (-1);
  206.     }
  207.     bytecount = td->td_stripbytecount[strip];
  208.     if (size != (u_int)-1 && size < bytecount)
  209.         bytecount = size;
  210.     return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
  211. }
  212.  
  213. /*
  214.  * Read the specified strip and setup for decoding. 
  215.  * The data buffer is expanded, as necessary, to
  216.  * hold the strip's data.
  217.  */
  218. static
  219. DECLARE2(TIFFFillStrip, TIFF*, tif, u_int, strip)
  220. {
  221.     static const char module[] = "TIFFFillStrip";
  222.     TIFFDirectory *td = &tif->tif_dir;
  223.     u_long bytecount;
  224.  
  225.     bytecount = td->td_stripbytecount[strip];
  226.     if (isMapped(tif) &&
  227.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  228.         /*
  229.          * The image is mapped into memory and we either don't
  230.          * need to flip bits or the compression routine is going
  231.          * to handle this operation itself.  In this case, avoid
  232.          * copying the raw data and instead just reference the
  233.          * data from the memory mapped file image.  This assumes
  234.          * that the decompression routines do not modify the
  235.          * contents of the raw data buffer (if they try to,
  236.          * the application will get a fault since the file is
  237.          * mapped read-only).
  238.          */
  239.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  240.             _TIFFfree(tif->tif_rawdata);
  241.         tif->tif_flags &= ~TIFF_MYBUFFER;
  242.         if (td->td_stripoffset[strip] + bytecount > tif->tif_size) {
  243.             /*
  244.              * This error message might seem strange, but it's
  245.              * what would happen if a read were done instead.
  246.              */
  247.             TIFFError(module, "%s: Read error on strip %d",
  248.                 tif->tif_name, strip);
  249.             tif->tif_curstrip = -1;        /* unknown state */
  250.             return (0);
  251.         }
  252.         tif->tif_rawdatasize = bytecount;
  253.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
  254.     } else {
  255.         /*
  256.          * Expand raw data buffer, if needed, to
  257.          * hold data strip coming from file
  258.          * (perhaps should set upper bound on
  259.          *  the size of a buffer we'll use?).
  260.          */
  261.         if (bytecount > tif->tif_rawdatasize) {
  262.             tif->tif_curstrip = -1;        /* unknown state */
  263.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  264.                 TIFFError(module,
  265.                 "%s: Data buffer too small to hold strip %d",
  266.                     tif->tif_name, strip);
  267.                 return (0);
  268.             }
  269.             if (!TIFFReadBufferSetup(tif, 0,
  270.                 roundup(bytecount, 1024)))
  271.                 return (0);
  272.         }
  273.         if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata,
  274.             bytecount, module) != bytecount)
  275.             return (0);
  276.         if (td->td_fillorder != tif->tif_fillorder &&
  277.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  278.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  279.     }
  280.     return (TIFFStartStrip(tif, strip));
  281. }
  282.  
  283. /*
  284.  * Tile-oriented Read Support
  285.  * Contributed by Nancy Cam (Silicon Graphics).
  286.  */
  287.  
  288. /*
  289.  * Read and decompress a tile of data.  The
  290.  * tile is selected by the (x,y,z,s) coordinates.
  291.  */
  292. int
  293. DECLARE6(TIFFReadTile,
  294.     TIFF*, tif, u_char*, buf, u_long, x, u_long, y, u_long, z, u_int, s)
  295. {
  296.     u_int tile;
  297.  
  298.     if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
  299.         return (-1);
  300.     tile = TIFFComputeTile(tif, x, y, z, s);
  301.     if (tile >= tif->tif_dir.td_nstrips) {
  302.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  303.             tile, tif->tif_dir.td_nstrips);
  304.         return (-1);
  305.     }
  306.     return (TIFFFillTile(tif, tile) &&
  307.         (*tif->tif_decodetile)(tif, buf, tif->tif_tilesize, s) ?
  308.         tif->tif_tilesize : -1);
  309. }
  310.  
  311. /*
  312.  * Read a tile of data and decompress the specified
  313.  * amount into the user-supplied buffer.
  314.  */
  315. int
  316. DECLARE4(TIFFReadEncodedTile,
  317.     TIFF*, tif, u_int, tile, u_char*, buf, u_long, size)
  318. {
  319.     TIFFDirectory *td = &tif->tif_dir;
  320.     u_long tilesize = tif->tif_tilesize;
  321.  
  322.     if (!TIFFCheckRead(tif, 1))
  323.         return (-1);
  324.     if (tile >= td->td_nstrips) {
  325.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  326.             tile, td->td_nstrips);
  327.         return (-1);
  328.     }
  329.     if (size == (u_int)-1)
  330.         size = tilesize;
  331.     else if (size > tilesize )
  332.         size = tilesize;
  333.     return (TIFFFillTile(tif, tile) && 
  334.         (*tif->tif_decodetile)(tif, buf, size, tile/td->td_stripsperimage) ?
  335.         size : -1);
  336. }
  337.  
  338. static int
  339. DECLARE5(TIFFReadRawTile1,
  340.     TIFF*, tif, u_int, tile, u_char*, buf, u_long, size,
  341.     const char*, module)
  342. {
  343.     TIFFDirectory *td = &tif->tif_dir;
  344.  
  345.     if (!isMapped(tif)) {
  346.         if (!SeekOK(tif, td->td_stripoffset[tile])) {
  347.             TIFFError(module,
  348.                 "%s: Seek error at row %d, col %d, tile %d",
  349.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  350.             return (-1);
  351.         }
  352.         if (!ReadOK(tif, buf, size)) {
  353.             TIFFError(module, "%s: Read error at row %d, col %d",
  354.                 tif->tif_name, tif->tif_row, tif->tif_col);
  355.             return (-1);
  356.         }
  357.     } else {
  358.         if (td->td_stripoffset[tile] + size > tif->tif_size) {
  359.             TIFFError(module,
  360.                 "%s: Seek error at row %d, col %d, tile %d",
  361.                 tif->tif_name, tif->tif_row, tif->tif_col, tile);
  362.             return (-1);
  363.         }
  364.         memcpy(buf, tif->tif_base + td->td_stripoffset[tile], size);
  365.     }
  366.     return (size);
  367. }
  368.  
  369. /*
  370.  * Read a tile of data from the file.
  371.  */
  372. int
  373. DECLARE4(TIFFReadRawTile, TIFF*, tif, u_int, tile, u_char*, buf, u_long, size)
  374. {
  375.     static const char module[] = "TIFFReadRawTile";
  376.     TIFFDirectory *td = &tif->tif_dir;
  377.     u_long bytecount;
  378.  
  379.     if (!TIFFCheckRead(tif, 1))
  380.         return (-1);
  381.     if (tile >= td->td_nstrips) {
  382.         TIFFError(tif->tif_name, "%d: Tile out of range, max %d",
  383.             tile, td->td_nstrips);
  384.         return (-1);
  385.     }
  386.     bytecount = td->td_stripbytecount[tile];
  387.     if (size != (u_int)-1 && size < bytecount)
  388.         bytecount = size;
  389.     return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));
  390. }
  391.  
  392. /*
  393.  * Read the specified tile and setup for decoding. 
  394.  * The data buffer is expanded, as necessary, to
  395.  * hold the tile's data.
  396.  */
  397. static
  398. DECLARE2(TIFFFillTile, TIFF*, tif, u_int, tile)
  399. {
  400.     static const char module[] = "TIFFFillTile";
  401.     TIFFDirectory *td = &tif->tif_dir;
  402.     u_long bytecount;
  403.  
  404.     bytecount = td->td_stripbytecount[tile];
  405.     if (isMapped(tif) &&
  406.         (td->td_fillorder == tif->tif_fillorder || (tif->tif_flags & TIFF_NOBITREV))) {
  407.         /*
  408.          * The image is mapped into memory and we either don't
  409.          * need to flip bits or the compression routine is going
  410.          * to handle this operation itself.  In this case, avoid
  411.          * copying the raw data and instead just reference the
  412.          * data from the memory mapped file image.  This assumes
  413.          * that the decompression routines do not modify the
  414.          * contents of the raw data buffer (if they try to,
  415.          * the application will get a fault since the file is
  416.          * mapped read-only).
  417.          */
  418.         if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
  419.             _TIFFfree(tif->tif_rawdata);
  420.         tif->tif_flags &= ~TIFF_MYBUFFER;
  421.         if (td->td_stripoffset[tile] + bytecount > tif->tif_size) {
  422.             tif->tif_curtile = -1;        /* unknown state */
  423.             return (0);
  424.         }
  425.         tif->tif_rawdatasize = bytecount;
  426.         tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile];
  427.     } else {
  428.         /*
  429.          * Expand raw data buffer, if needed, to
  430.          * hold data tile coming from file
  431.          * (perhaps should set upper bound on
  432.          *  the size of a buffer we'll use?).
  433.          */
  434.         if (bytecount > tif->tif_rawdatasize) {
  435.             tif->tif_curtile = -1;        /* unknown state */
  436.             if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
  437.                 TIFFError(module,
  438.                 "%s: Data buffer too small to hold tile %d",
  439.                     tif->tif_name, tile);
  440.                 return (0);
  441.             }
  442.             if (!TIFFReadBufferSetup(tif, 0,
  443.                 roundup(bytecount, 1024)))
  444.                 return (0);
  445.         }
  446.         if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata,
  447.             bytecount, module) != bytecount)
  448.             return (0);
  449.         if (td->td_fillorder != tif->tif_fillorder &&
  450.             (tif->tif_flags & TIFF_NOBITREV) == 0)
  451.             TIFFReverseBits((u_char *)tif->tif_rawdata, bytecount);
  452.     }
  453.     return (TIFFStartTile(tif, tile));
  454. }
  455.  
  456. /*
  457.  * Setup the raw data buffer in preparation for
  458.  * reading a strip of raw data.  If the buffer
  459.  * is specified as zero, then a buffer of appropriate
  460.  * size is allocated by the library.  Otherwise,
  461.  * the client must guarantee that the buffer is
  462.  * large enough to hold any individual strip of
  463.  * raw data.
  464.  */
  465. int
  466. DECLARE3(TIFFReadBufferSetup, TIFF*, tif, char*, bp, u_long, size)
  467. {
  468.     static const char module[] = "TIFFReadBufferSetup";
  469.  
  470.     if (tif->tif_rawdata) {
  471.         if (tif->tif_flags & TIFF_MYBUFFER)
  472.             _TIFFfree(tif->tif_rawdata);
  473.         tif->tif_rawdata = NULL;
  474.     }
  475.     if (bp) {
  476.         tif->tif_rawdatasize = size;
  477.         tif->tif_rawdata = bp;
  478.         tif->tif_flags &= ~TIFF_MYBUFFER;
  479.     } else {
  480.         tif->tif_rawdatasize = roundup(size, 1024);
  481.         tif->tif_rawdata = _TIFFmalloc(tif->tif_rawdatasize);
  482.         tif->tif_flags |= TIFF_MYBUFFER;
  483.     }
  484.     if (tif->tif_rawdata == NULL) {
  485.         TIFFError(module,
  486.             "%s: No space for data buffer at scanline %d",
  487.             tif->tif_name, tif->tif_row);
  488.         tif->tif_rawdatasize = 0;
  489.         return (0);
  490.     }
  491.     return (1);
  492. }
  493.  
  494. /*
  495.  * Set state to appear as if a
  496.  * strip has just been read in.
  497.  */
  498. static int
  499. DECLARE2(TIFFStartStrip, TIFF*, tif, u_int, strip)
  500. {
  501.     TIFFDirectory *td = &tif->tif_dir;
  502.  
  503.     tif->tif_curstrip = strip;
  504.     tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
  505.     tif->tif_rawcp = tif->tif_rawdata;
  506.     tif->tif_rawcc = td->td_stripbytecount[strip];
  507.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  508. }
  509.  
  510. /*
  511.  * Set state to appear as if a
  512.  * tile has just been read in.
  513.  */
  514. static int
  515. DECLARE2(TIFFStartTile, TIFF*, tif, u_int, tile)
  516. {
  517.     TIFFDirectory *td = &tif->tif_dir;
  518.  
  519.     tif->tif_curtile = tile;
  520.     tif->tif_row =
  521.         (tile % howmany(td->td_imagewidth, td->td_tilewidth)) *
  522.         td->td_tilelength;
  523.     tif->tif_col =
  524.         (tile % howmany(td->td_imagelength, td->td_tilelength)) *
  525.         td->td_tilewidth;
  526.     tif->tif_rawcp = tif->tif_rawdata;
  527.     tif->tif_rawcc = td->td_stripbytecount[tile];
  528.     return (tif->tif_predecode == NULL || (*tif->tif_predecode)(tif));
  529. }
  530.  
  531. static int
  532. DECLARE2(TIFFCheckRead, TIFF*, tif, int, tiles)
  533. {
  534.     if (tif->tif_mode == O_WRONLY) {
  535.         TIFFError(tif->tif_name, "File not open for reading");
  536.         return (0);
  537.     }
  538.     if (tiles ^ isTiled(tif)) {
  539.         TIFFError(tif->tif_name, tiles ?
  540.             "Can not read tiles from a stripped image" :
  541.             "Can not read scanlines from a tiled image");
  542.         return (0);
  543.     }
  544.     return (1);
  545. }
  546.